package alarm

import (
	"fmt"
	"sort"
	"strconv"
	"strings"
	"system-admin/config/mysql"
	"system-admin/internal/define"
	"system-admin/internal/models"

	"192.168.1.75/go-pkg/errorx"
	"192.168.1.75/go-pkg/helper"
	"gorm.io/gorm"
)

// GetAlarmReceiveStatus 获取告警接收状态
func GetAlarmReceiveStatus(loginUserID string) (status int) {
	var count int64
	// 不是告警接收用户，直接返回-1
	mysql.NewDB().Model(&models.AlarmNotifyRule{}).
		Where("receive_users LIKE ?", "%,"+loginUserID+",%").
		Or("receive_users LIKE ?", loginUserID+",%").
		Or("receive_users LIKE ?", "%,"+loginUserID).
		Or("receive_users = ?", loginUserID).
		Count(&count)
	if count <= 0 {
		return -1
	}
	// 获取用户的设置
	var user models.User
	mysql.NewDB().Model(&models.User{}).
		Where("id = ?", loginUserID).
		Take(&user)
	return user.AlarmReceive
}

// SetAlarmReceiveStatus  设置告警接收状态
func SetAlarmReceiveStatus(loginUserID string, status int) (err error) {
	var count int64
	// 不是告警接收用户，直接返回
	mysql.NewDB().Model(&models.AlarmNotifyRule{}).
		Where("receive_users LIKE ?", "%,"+loginUserID+",%").
		Or("receive_users LIKE ?", loginUserID+",%").
		Or("receive_users LIKE ?", "%,"+loginUserID).
		Or("receive_users = ?", loginUserID).
		Count(&count)
	if count <= 0 {
		return errorx.New("暂不是告警接收用户", -1)
	}
	// 更新用户设置
	rowsAffected := mysql.NewDB().Model(&models.User{}).Where("id = ?", loginUserID).
		Update("alarm_receive", status).
		RowsAffected
	if rowsAffected > 0 {
		return nil
	} else {
		return errorx.New("设置失败", -1)
	}
}

// GetAlarmTypes 获取告警类型
func GetAlarmTypes() interface{} {
	type alartmTypeT struct {
		ID      int    `json:"id"`
		Name    string `json:"name"`
		Visible bool   `json:"visible"`
	}
	var alarmTypes []alartmTypeT
	for k, v := range define.AlarmType {
		alarmCode := ""
		if k < 50 {
			alarmCode = fmt.Sprintf("(0x%02x)", k)
		}
		alarmTypes = append(alarmTypes, alartmTypeT{
			ID:      k,
			Name:    v.Name + alarmCode,
			Visible: v.Visible,
		})
	}
	// key排序
	sort.SliceStable(alarmTypes, func(i, j int) bool {
		return alarmTypes[i].ID < alarmTypes[j].ID
	})
	return alarmTypes
}

// GetNotifyTypes 获取通知方式
func GetNotifyTypes() interface{} {
	type notifyTypeT struct {
		ID   int    `json:"id"`
		Name string `json:"name"`
	}
	var notifyTypes []notifyTypeT
	for k, v := range define.NotifyType {
		notifyTypes = append(notifyTypes, notifyTypeT{
			ID:   k,
			Name: v,
		})
	}
	// key排序
	sort.SliceStable(notifyTypes, func(i, j int) bool {
		return notifyTypes[i].ID < notifyTypes[j].ID
	})
	return notifyTypes
}

// NotifyRuleList 通知规则列表
func NotifyRuleList(merchantID string, page int, limit int) (res interface{}, total int64, err error) {
	type retType struct {
		models.AlarmNotifyRule
		AlarmTypeNames   string `json:"alarm_type_names" gorm:"-"`
		ReceiveUserNames string `json:"receive_user_names" gorm:"-"`
		NotifyTypeNames  string `json:"notify_type_names" gorm:"-"`
	}
	var list []retType

	tx := mysql.NewDB().Model(&models.AlarmNotifyRule{}).
		Omit("merchant_id").
		Where("merchant_id = ?", merchantID).
		Session(&gorm.Session{})

	// 获取总条数
	var count int64
	tx.Count(&count)

	helper.Gorm{}.Paginate(tx, page, limit).Find(&list)
	// 增加报警类型，接收用户，通知类型名称
	for index, rule := range list {
		var (
			alarmTypeNames   []string
			receiveUserNames []string
			notifyTypeNames  []string
		)
		// 报警类型名称
		alarmTypeArr := strings.Split(rule.AlarmTypes, ",")
		for _, v := range alarmTypeArr {
			typeInt, err := strconv.Atoi(v)
			if err == nil {
				alarmTypeNames = append(alarmTypeNames, define.AlarmType[typeInt].Name)
			}
		}
		list[index].AlarmTypeNames = strings.Join(alarmTypeNames, ",")
		// 通知类型名称
		notifyTypeArr := strings.Split(rule.NotifyTypes, ",")
		for _, v := range notifyTypeArr {
			typeInt, err := strconv.Atoi(v)
			if err == nil {
				notifyTypeNames = append(notifyTypeNames, define.NotifyType[typeInt])
			}
		}
		list[index].NotifyTypeNames = strings.Join(notifyTypeNames, ",")
		// 接收用户姓名
		var users []models.User
		receiveUserArr := strings.Split(rule.ReceiveUsers, ",")
		mysql.NewDB().Model(&models.User{}).Where("id IN ?", receiveUserArr).Find(&users)
		for _, user := range users {
			receiveUserNames = append(receiveUserNames, user.Username)
		}
		list[index].ReceiveUserNames = strings.Join(receiveUserNames, ",")
	}
	return list, count, nil
}

// AddNotifyRule 新增通知规则
// name 规则名称
// merchantID 所属商户
// robotIDs 设备id
// alarmTypes 告警类型
// receiveUsers 接收用户
// notifyTypes  通知方式
func AddNotifyRule(name string, merchantID string, robotIDs string, alarmTypes string, receiveUsers string, notifyTypes string) (string, error) {
	// 字段合法性检查
	name = strings.TrimSpace(name)
	if name == "" {
		return "", errorx.New("规则名称不能为空")
	}
	if len(alarmTypes) == 0 {
		return "", errorx.New("告警类型不能为空")
	}
	if len(receiveUsers) == 0 {
		return "", errorx.New("接收用户不能为空")
	}
	if len(notifyTypes) == 0 {
		return "", errorx.New("通知方式不能为空")
	}

	// 插入规则
	var rule models.AlarmNotifyRule
	rule.Name = name
	rule.MerchantID = merchantID
	rule.RobotIDs = robotIDs
	rule.AlarmTypes = alarmTypes
	rule.ReceiveUsers = receiveUsers
	rule.NotifyTypes = notifyTypes
	rowsAffected := mysql.NewDB().
		Model(&models.AlarmNotifyRule{}).
		Create(&rule).
		RowsAffected

	if rowsAffected <= 0 {
		return "", errorx.New("创建规则失败", -1)
	}

	return rule.ID, nil
}

// EditNotifyRule 修改通知规则
// ruleID 规则id
// name 规则名称
// merchantID 商户id
// robotIDs 设备id
// alarmTypes 告警类型
// receiveUsers 接收
// notifyTypes 通知类型
func EditNotifyRule(ruleID string, name string, merchantID string, robotIDs string, alarmTypes string, receiveUsers string, notifyTypes string) error {
	// 判断规则是否存在
	if ruleID == "" {
		return errorx.New("规则id不能为空")
	}
	var count int64
	mysql.NewDB().Model(&models.AlarmNotifyRule{}).Where(models.AlarmNotifyRule{
		ID: ruleID,
	}).Count(&count)
	if count <= 0 {
		return errorx.New("规则不存在", -1)
	}
	// 判断名称是否存在
	var oldRule models.AlarmNotifyRule
	rowsAffected := mysql.NewDB().Model(&models.AlarmNotifyRule{}).Where(models.AlarmNotifyRule{
		MerchantID: merchantID,
		Name:       name,
	}).
		Take(&oldRule).
		RowsAffected
	if rowsAffected > 0 && oldRule.ID != ruleID {
		return errorx.New("规则名称已存在")
	}

	// 更新规则
	var rule models.AlarmNotifyRule
	rule.Name = name
	rule.MerchantID = merchantID
	rule.RobotIDs = robotIDs
	rule.AlarmTypes = alarmTypes
	rule.ReceiveUsers = receiveUsers
	rule.NotifyTypes = notifyTypes
	rowsAffected = mysql.NewDB().
		Model(&models.AlarmNotifyRule{}).
		Where("id = ?", ruleID).
		Updates(&rule).
		RowsAffected

	if rowsAffected <= 0 {
		return errorx.New("更新规则失败", -1)
	}
	return nil
}

// DeleteNotifyRule 删除告警规则
// ruleID 规则ID
func DeleteNotifyRule(ruleID string, merchantID string) error {
	rowsAffected := mysql.NewDB().Model(&models.AlarmNotifyRule{}).
		Where(models.AlarmNotifyRule{
			ID:         ruleID,
			MerchantID: merchantID,
		}).
		Delete(&models.AlarmNotifyRule{}).
		RowsAffected
	if rowsAffected <= 0 {
		return errorx.New("删除失败", -1)
	}
	return nil
}
